#pragma once
#include "tinyrpc/base/noncopyable.h"
#include "epoller.h"
#include <memory>
#include <unordered_map>
#include <vector>
#include <mutex>
#include "event.h"
#include "channel/wakeupchannel.h"
#include "timerque.h"
namespace TinyRPC
{
class Task;

enum EventLoopStatus{
    STATUS_EPOLLWAIT,
    STATUS_HANDLEEVENT,
    STATUS_DOTASK
};

class EventLoop : public Noncopyable {
public:
    EventLoop();
    void loop();
    // 添加任务
    void queueInLoop(const Task& task);
    void runInLoop(const Task& task);
    void setOwnerThread(pid_t tid);

    void modifyEvent(EventPtr event);
    void deleteEvent(EventPtr event);
    void addEvent(EventPtr event);
    
    void wakeup();
    
    
    void runAfter(float sec, const Task& task);
    // 定时器api, 这里面的Task最好不要是协程
    void runEvery(float sec, float interval, const Task& task);
    void addTimer(const Timer& timer);

    // 退出
    void quit();

    static EventLoop* CurrentEventLoop();
private:
    void doTask();

private:
    // event 将不再被EventLoop管理， 而是被各自的Channel管理
    //std::unordered_map<int, EventPtr> m_registedEvents;
    std::unique_ptr<EPoller> m_epoller;
    std::vector<Event*> m_activateEvents;
    bool m_quit;

    pid_t m_ownerThreadTid;

    std::vector<Task> m_taskList;
    std::mutex m_mutex;

    WakeupChannel m_wakeupChannel;
    TimerQueue m_timerQueue;
    EventLoopStatus m_status;

    
};  


extern thread_local EventLoop* currentEventLoop;
} // namespace TinyRPC

